import { Merchant } from '@app/db/entities/Merchant';
import { WithdrawalRecord } from '@app/db/entities/WithdrawalRecord';
import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';

@Injectable()
export class WithdrawalService {
    constructor(
        @InjectDataSource() protected readonly dataSource: DataSource
    ){}


    //通过
    async pass(id:number) {
        const queryRunner = await this.dataSource.createQueryRunner()
        await queryRunner.connect();
        await queryRunner.startTransaction();

        try {
            let record = await queryRunner.manager.findOne<WithdrawalRecord>(WithdrawalRecord, {
                where : {id : id},
                select : ['merchantId', 'amount', 'status'],
                lock : {
                    mode : 'pessimistic_read'
                }
            })

            if(!record || record.status != 0) {
                await queryRunner.rollbackTransaction()
                return null
            }

            let merchant = await queryRunner.manager.findOne<Merchant>(Merchant, {
                where : {id : record.merchantId},
                select : ['frozenAmount'],
                lock : {
                    mode : 'pessimistic_read'
                }
            })

            if(!merchant) {
                await queryRunner.rollbackTransaction()
                return null
            }

            const r1 = await queryRunner.manager.update<WithdrawalRecord>(WithdrawalRecord, {id : id}, {
                status : 1,
                completeTime : Math.floor(Date.now() / 1000)
            })

            if(r1.affected < 1) {
                await queryRunner.rollbackTransaction();
                return -1
            }

            const amount = Number(record.amount)


            const r2 = await queryRunner.manager.update<Merchant>(Merchant, {id : record.merchantId}, {
                frozenAmount : (Number(merchant.frozenAmount) - amount).toFixed(2),
            })

            if(r2.affected < 1) {
                await queryRunner.rollbackTransaction();
                return -2
            }

            await queryRunner.commitTransaction()

            return true

        } catch (error) {
            await queryRunner.rollbackTransaction();
            return null
        } finally {
            await queryRunner.release();
        }
    }
    async refuse(id:number, reason:string) {
        const queryRunner = await this.dataSource.createQueryRunner()
        await queryRunner.connect();
        await queryRunner.startTransaction();

        try {
            let record = await queryRunner.manager.findOne<WithdrawalRecord>(WithdrawalRecord, {
                where : {id : id},
                select : ['merchantId', 'amount', 'status'],
                lock : {
                    mode : 'pessimistic_read'
                }
            })

            if(!record || record.status != 0) {
                await queryRunner.rollbackTransaction()
                return null
            }

            let merchant = await queryRunner.manager.findOne<Merchant>(Merchant, {
                where : {id : record.merchantId},
                select : ['amount', 'frozenAmount'],
                lock : {
                    mode : 'pessimistic_read'
                }
            })

            if(!merchant) {
                await queryRunner.rollbackTransaction()
                return null
            }

            const r1 = await queryRunner.manager.update<WithdrawalRecord>(WithdrawalRecord, {id : id}, {
                status : 2,
                completeTime : Math.floor(Date.now() / 1000),
                reason : reason || ''
            })

            if(r1.affected < 1) {
                await queryRunner.rollbackTransaction();
                return -1
            }

            const amount = Number(record.amount)


            const r2 = await queryRunner.manager.update<Merchant>(Merchant, {id : record.merchantId}, {
                amount : (Number(merchant.amount) + amount).toFixed(2),
                frozenAmount : (Number(merchant.frozenAmount) - amount).toFixed(2),
            })

            if(r2.affected < 1) {
                await queryRunner.rollbackTransaction();
                return -2
            }

            await queryRunner.commitTransaction()

            return true

        } catch (error) {
            await queryRunner.rollbackTransaction();
            return null
        } finally {
            await queryRunner.release();
        }
    }
}
